package com.atguigu.tingshu.common.login;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Slf4j
@Component
public class TsLoginAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Around(value = "execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(tsLogin)")
    public Object tsLoginAspectAround(ProceedingJoinPoint joinPoint,TsLogin tsLogin) throws Throwable {
        Object o = new Object();
        //其中一种写法 太麻烦 用另一种
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        boolean b = signature.getMethod().getAnnotation(TsLogin.class).requiredLogin();
        //获取请求头中token
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        String token = requestAttributes.getRequest().getHeader("token");
        //如果是true说明需要判断是否登录
        if (tsLogin.requiredLogin()){
            if (StringUtils.isEmpty(token)){
                //未登录抛出异常
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
            //token不为空 去缓存中查用户数据，判断用户数据是否为空
            //创建redis中key
            String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
            UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(userLoginKey);
            if (ObjectUtils.isEmpty(userInfo)){
                //未登录抛出异常
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
        }
        if (!StringUtils.isEmpty(token)){
            //token不为空 去缓存中查用户数据，判断用户数据是否为空
            //创建redis中key
            String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
            UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(userLoginKey);
            if (!ObjectUtils.isEmpty(userInfo)){
                //存储用户id
                AuthContextHolder.setUserId(userInfo.getId());
            }
        }
        o = joinPoint.proceed();
        //返回数据
        return o;
    }
}
